<template>
  <span class="image-box">
    <el-upload
      v-if="!inputDisabled"
      :class="['cm-image', {'is-disabled': inputDisabled}]" action=""
      :disabled="inputDisabled"
      :http-request = "handleUpload"
      :show-file-list="false"
      :accept="'image/*'"
      :before-upload="handleBeforeUpload"
    >
      <i class="fa fa-plus plus-icon"></i>
    </el-upload>

    <el-image-viewer
      v-if="showViewer"
      :z-index="5000"
      :onClose="() => { showViewer = false}"
      :url-list="viewUrls"
    />

    <span v-for="(item, index) in fileList" class="file" :key="index">
      <span class="file-item" :class="[{'is-disabled': inputDisabled}]">
        <span class="file-box" :title="item.name">
          <img
            v-if="item.status === 2"
            :src="baseUrl + '/affix/image/' + item.id"
            @click="previewImage(item.id)"
            alt
          />
          <i v-else class="el-icon-loading loading-icon"></i>
        </span>
        <span
          v-if="!inputDisabled && item.status === 2"
          class="el-icon-delete file-delete"
          title="删除"
          @click="deleteFile(item)"
        ></span>
      </span>
    </span>
  </span>
</template>

<script setup>
import {ref, watch, onMounted} from 'vue';
import api from "@/http/api";
import tool from '@/utils/tool';
import {ElMessage, ElMessageBox} from "element-plus";

const emit = defineEmits(['update:modelValue', 'change']);
const props = defineProps({
  modelValue: [Number, String],
  inputDisabled: Boolean
});

const baseUrl = ref(import.meta.env.VITE_BASE_PATH);
const uploadCnt = ref(0);
const affixId = ref('');
const fileList = ref([]);
const showViewer = ref(false);
const viewUrls = ref([]);

const handleUpload = (file) => {
  return new Promise((resolve, reject) => {
    api.upload({'file': file.file, 'affixId': affixId.value}).then((res) => {
      uploadCnt.value--;
      let filters = fileList.value.filter(item => item.name === res.data.trueName && item.status === 1);
      if (filters.length > 0) {
        filters[0].id = res.data.id;
        filters[0].status = 2;
      }
      resolve();
    }).catch(() => {
      uploadCnt.value--;
      reject();
    });
  });
};

const handleBeforeUpload = (file) => {
  if (affixId.value == null || affixId.value === '') {
    affixId.value = tool.uuid();
    emit('update:modelValue', affixId.value);
  }

  let isLt = file.size / 1024 / 1024 < 2;
  if (!isLt) {
    ElMessage.error("上传图片不能超过 2MB!");
  } else {
    fileList.value.push({name: file.name, status: 1});
    uploadCnt.value++;
  }

  return isLt;
};

const deleteFile = (file) => {
  ElMessageBox.confirm('请确认是否删除此图片？', '提示', {type: 'info'}).then(() => {
    api.deleteAffix(file.id).then(() => {
      fileList.value = fileList.value.filter(item => item.id !== file.id)
      if(fileList.value.length === 0){
        affixId.value = '';
      }
    });
  }).catch(()=>{});
};

const previewImage = (id) => {
  let views = [];
  fileList.value.filter(item => item.id === id && item.status === 2).forEach(item => {
    views.push(baseUrl.value + '/affix/image/' + item.id);
  });
  fileList.value.filter(item => item.id !== id && item.status === 2).forEach(item => {
    views.push(baseUrl.value + '/affix/image/' + item.id);
  });
  viewUrls.value = views;
  showViewer.value = true;
};

const loadData = () => {
  fileList.value = [];
  if (typeof props.modelValue !== "undefined" && props.modelValue != null && props.modelValue !== "") {
    api.queryAffix(props.modelValue).then((res) => {
      if(res.data.length > 0){
        affixId.value = props.modelValue;
        for (let i=0;i<res.data.length;i++) {
          fileList.value.push({name: res.data[i].trueName, id: res.data[i].id, status: 2});
        }
      } else {
        affixId.value = '';
      }
    }).catch((res) => {
      ElMessage.error(res.message);
    });
  } else {
    affixId.value = '';
  }
};

watch(() => props.modelValue, (newVal) => {
  if (newVal === undefined || newVal == null || newVal === ''
    || affixId.value === undefined || affixId.value === null || affixId.value === ''
    || newVal !== affixId.value) {
    loadData();
  }
});

onMounted(() => {
  loadData();
});
</script>

<style scoped>
.image-box {
  width: 100%;
  height: 100%;
  display: flex;
  flex-flow: wrap;
  margin-bottom: 10px;
}
.image-box img {
  max-width: 100%;
}
.image-box .file-item {
  width: 90px;
  height: 90px;
  border: 1px dashed #c2c2c2;
  margin-right: 8px;
  margin-bottom: 8px;
  cursor: pointer;
}
.image-box .file-box {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }
.image-box .file-item .file-delete {
  position: relative;
  top: -95px;
  right: -70px;
  cursor: pointer;
  color: red;
  font-weight: bolder;
}
.image-box .file-item img {
  max-height: 100%;
  max-width: 100%;
}
.cm-image {
  height: 90px;
  width: 90px;
  justify-content: center;
  align-items: center;
  display: flex;
  border: 1px dashed #c2c2c2;
  margin-right: 8px;
  margin-bottom: 8px;
}
.cm-image :deep(.el-upload) {
  display: flex;
  text-align: center;
  cursor: pointer;
  outline: 0;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}
.cm-image :deep(.el-upload span) {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.cm-image:not(.is-disabled) :deep(.el-upload) {
  cursor: pointer;
}
.cm-image:not(.is-disabled) :deep(.el-upload:hover) {
  border-color: #409EFF;
}
.loading-icon {
  font-size: 28px;
  color: #8c939d;
  position: absolute;
}
.plus-icon {
  font-size: 28px;
  color: #8c939d;
  position: absolute;
}
.cm-image img {
  max-width: 100%;
  max-height: 100%;
}
</style>